home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / x+opengl / glxmotif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  6.9 KB  |  227 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* $Revision: 1.8 $ */
  18. /* compile: cc -o glxmotif glxmotif.c -lGLU -lGL -lXm -lXt -lX11 */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <Xm/Form.h>
  22. #include <Xm/Frame.h>
  23. #include <Xm/DrawingA.h>
  24. #include <X11/keysym.h>
  25. #include <GL/gl.h>
  26. #include <GL/glu.h>
  27. #include <GL/glx.h>
  28.  
  29. static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
  30. static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
  31. static String   fallbackResources[] = {
  32.     "*glxarea*width: 300", "*glxarea*height: 300",
  33.     "*frame*x: 20", "*frame*y: 20",
  34.     "*frame*topOffset: 20", "*frame*bottomOffset: 20",
  35.     "*frame*rightOffset: 20", "*frame*leftOffset: 20",
  36.     "*frame*shadowType: SHADOW_IN",
  37.     NULL
  38. };
  39.  
  40. Display        *dpy;
  41. GLboolean       doubleBuffer = GL_TRUE, viewportUpdateNeeded = GL_TRUE, spinning = GL_FALSE;
  42. XtAppContext    app;
  43. XtWorkProcId    workId = 0;
  44. Widget          toplevel, form, frame, glxarea;
  45.  
  46. void
  47. updateViewport(Widget w)
  48. {
  49.     Dimension width, height;
  50.  
  51.     XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
  52.     glViewport(0, 0, (GLint) width, (GLint) height);
  53.     viewportUpdateNeeded = GL_FALSE;
  54. }
  55.  
  56. void
  57. draw(Widget w)
  58. {
  59.     if (viewportUpdateNeeded) updateViewport(w);
  60.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  61.     glBegin(GL_POLYGON);
  62.     glColor3f(0.0, 0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
  63.     glColor3f(0.7, 0.7, 0.7); glVertex3f(10.0, -10.0, 0.0);
  64.     glColor3f(1.0, 1.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
  65.     glEnd();
  66.     glBegin(GL_POLYGON);
  67.     glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, -10.0, -10.0);
  68.     glColor3f(0.0, 1.0, 0.7); glVertex3f(0.0, -10.0, 10.0);
  69.     glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 5.0, -10.0);
  70.     glEnd();
  71.     glBegin(GL_POLYGON);
  72.     glColor3f(1.0, 1.0, 0.0); glVertex3f(-10.0, 6.0, 4.0);
  73.     glColor3f(1.0, 0.0, 1.0); glVertex3f(-10.0, 3.0, 4.0);
  74.     glColor3f(0.0, 0.0, 1.0); glVertex3f(4.0, -9.0, -10.0);
  75.     glColor3f(1.0, 0.0, 1.0); glVertex3f(4.0, -6.0, -10.0);
  76.     glEnd();
  77.     if (doubleBuffer) glXSwapBuffers(dpy, XtWindow(w));
  78.     glFlush();
  79. }
  80.  
  81. void
  82. expose(Widget w, XtPointer clientData, XtPointer callData)
  83. {
  84.     draw(w);
  85. }
  86.  
  87. void
  88. resize(Widget w, XtPointer clientData, XtPointer callData)
  89. {
  90.     XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
  91.  
  92.     /* don't try OpenGL until window is realized! */
  93.     if (XtIsRealized(w)) updateViewport(w);
  94.         else viewportUpdateNeeded = GL_TRUE;
  95. }
  96.  
  97. Boolean
  98. spin(XtPointer clientData)
  99. {
  100.     glRotatef(2.5, 1.0, 0.0, 0.0);
  101.     draw(glxarea);
  102.     return False; /* leave work proc active */
  103. }
  104.  
  105. void
  106. input(Widget w, XtPointer clientData, XtPointer callData)
  107. {
  108.     XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
  109.     char            buffer[1];
  110.     KeySym          keysym;
  111.     int             rc;
  112.  
  113.     switch (cd->event->type) {
  114.     case KeyRelease:
  115.     /*
  116.      * It is necessary to convert the keycode to a keysym before it is
  117.      * possible to check if it is an escape
  118.      */
  119.     rc = XLookupString((XKeyEvent *) cd->event, buffer, 1, &keysym, NULL);
  120.     switch (keysym) {
  121.     case XK_Up:
  122.         glRotatef(10.0, 0.0, 0.0, 1.0);
  123.         if (!spinning) draw(w);
  124.         break;
  125.     case XK_Down:
  126.         glRotatef(-10.0, 0.0, 0.0, 1.0);
  127.         if (!spinning) draw(w);
  128.         break;
  129.     case XK_Left:
  130.         glRotatef(-10.0, 0.0, 1.0, 0.0);
  131.         if (!spinning) draw(w);
  132.         break;
  133.     case XK_Right:
  134.         glRotatef(10.0, 0.0, 1.0, 0.0);
  135.         if (!spinning) draw(w);
  136.         break;
  137.     case XK_S: case XK_s: /* the S key */
  138.         if (spinning) {
  139.         XtRemoveWorkProc(workId);
  140.         spinning = GL_FALSE;
  141.         } else {
  142.         workId = XtAppAddWorkProc(app, spin, NULL);
  143.         spinning = GL_TRUE;
  144.         }
  145.         break;
  146.     case XK_Escape:
  147.         exit(0);
  148.     }
  149.     break;
  150.     }
  151. }
  152.  
  153. void
  154. map_state_changed(Widget w, XtPointer clientData, XEvent * event, Boolean * cont)
  155. {
  156.     switch (event->type) {
  157.     case MapNotify:
  158.     if (spinning && workId != 0) workId = XtAppAddWorkProc(app, spin, NULL);
  159.     break;
  160.     case UnmapNotify:
  161.     if (spinning) XtRemoveWorkProc(workId);
  162.     break;
  163.     }
  164. }
  165.  
  166. main(int argc, char *argv[])
  167. {
  168.     XVisualInfo    *vi;
  169.     Colormap        cmap;
  170.     GLXContext      cx;
  171.     int            saved_argc;
  172.     String       *saved_argv;
  173.  
  174.     toplevel = XtAppInitialize(&app, "Glxmotif", NULL, 0, &argc, argv,
  175.                                fallbackResources, NULL, 0);
  176.     dpy = XtDisplay(toplevel);
  177.  
  178.     /* find an OpenGL-capable RGB visual with depth buffer */
  179.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
  180.     if (vi == NULL) {
  181.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
  182.     if (vi == NULL) XtAppError(app, "no RGB visual with depth buffer");
  183.     doubleBuffer = GL_FALSE;
  184.     }
  185.     /* create an OpenGL rendering context */
  186.     cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE);
  187.     if (cx == NULL) XtAppError(app, "could not create rendering context");
  188.     /* create an X colormap since probably not using default visual */
  189.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
  190.  
  191.     XtVaSetValues(toplevel, XtNvisual, vi->visual, XtNdepth, vi->depth,
  192.        XtNcolormap, cmap, NULL);
  193.     XtAddEventHandler(toplevel, StructureNotifyMask, False, map_state_changed, NULL);
  194.  
  195.     form = XmCreateForm(toplevel, "form", NULL, 0);
  196.     XtManageChild(form);
  197.  
  198.     frame = XmCreateFrame(form, "frame", NULL, 0);
  199.     XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
  200.         XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
  201.         XmNrightAttachment, XmATTACH_FORM, NULL);
  202.     XtManageChild(frame);
  203.  
  204.     glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame, NULL, 0);
  205.     XtAddCallback(glxarea, XmNexposeCallback, expose, NULL);
  206.     XtAddCallback(glxarea, XmNresizeCallback, resize, NULL);
  207.     XtAddCallback(glxarea, XmNinputCallback, input, NULL);
  208.  
  209.     XtRealizeWidget(toplevel);
  210.  
  211.     /* Once widget is realized (ie, associated with a created X window), we
  212.      * can bind the OpenGL rendering context to the window.
  213.      */
  214.     glXMakeCurrent(dpy, XtWindow(glxarea), cx);
  215.  
  216.     /* setup OpenGL state */
  217.     glEnable(GL_DEPTH_TEST);
  218.     glDepthFunc(GL_LEQUAL); 
  219.     glClearDepth(1.0);
  220.     glClearColor(0.0, 0.0, 0.0, 0.0);
  221.     glLoadIdentity();
  222.     gluPerspective(40.0, 1.0, 10.0, 200.0);
  223.     glTranslatef(0.0, 0.0, -50.0); glRotatef(-58.0, 0.0, 1.0, 0.0);
  224.  
  225.     XtAppMainLoop(app);
  226. }
  227.